Integration Guide for Robots by Stäubli

Note: This integration guide describes the Robot module for an older version of the communication interface (BPS 1.6). The module works with the current Bin Picking Studio (BPS) because of backward compatibility. It does not support features added later.

Note: We strongly recommend that you read the Robot communication overview before this integration guide.

Contents

1 Prerequisites

The Photoneo Stäubli interface was developed with the CS9 controller version s8.12.2-Cs9_BS2561.

It should also work with older CS8 controllers after some changes (mostly in the UI). The required VAL3 version is s7.7.2 or higher.

Note: We strongly recommend that you use Stäubli Robotics Suite 2016.6.1 or higher to install the Robot module.

2 Robot controller setup

2.1 Controller configuration

2.1.1 Network configuration

The first step of the setup is to configure the network interfaces.

Turn on the robot controller and wait until it starts. Then open Settings and select Network:

Staubli Network

There are two network interfaces:

  • J204

    • Usually used for communication with third-party devices. Here, this is the vision controller.

    • Configure the IP address to match the network configuration of the vision controller (check the network interface of the vision controller).

  • J205

    • Usually used for file transfers between the Stäubli Robotics Suite and the robot controller.

    • Configure the IP address to match the network configuration of the PC that runs the Stäubli Robotics Suite.

Staubli IP change

2.2 Robot module installation

Start the Stäubli Robotics Suite (SRS) to configure the SRS project.

2.2.1 Creating a new SRS project

Select New -> New cell wizard.

Staubli New project

Enter the project name and select the project location.

Staubli New project name

The robot controller should already be connected. Select Add a local controller from a remote controller.

Adding the controller

To select a controller from the available targets, click the “…” button.

Selecting the controller

In the General Informations section, fill in this field:

  • Host - the IP address of the J205 network interface of the robot controller

The Remote Connection section contains the login information. Fill in these fields:

  • User Name: maintenance

  • Password: spec_cal

  • Port: 5653

Connecting to the controller

Click OK and then Next.

Finishing controller setup 1

On the Finish page, click Finish to transfer the controller.

Finishing controller setup 2

The controller is transferred.

Finishing controller setup 3

2.2.2 Loading the Robot module files

You must transfer the Robot module files to the robot controller. First, load them into the SRS project.

The Robot module consists of two core folders with val3 files:

  • photoneo_common

  • customer_definitions

Photoneo also provides three bin picking example programs and one semi-automatic calibration example program in the example_programs folder:

  • main_basic

  • main_multiple_vs

  • main_change_solution

  • main_calibration

Copy the core folders (and, optionally, the example program that you want to use) to the usrapp folder of your project. In this example, the folder is:

~/Documents/Staubli/SRS/Staubli BPS/Controller1/usr/usrapp

After you copy the files into the folder, open the applications in the SRS project. Go to the Cell Explorer and expand the project (Stabuli BPS). Right-click the controller name (Controller1). Open both core applications and, optionally, the example program that you want to use. To open an application, select its .pjx file.

Open applications 1

The resulting project structure is shown in the figure below:

Open applications 2

2.2.3 Changing the cartesian origin of the robot

The Cartesian origin of Stäubli robots is different from the Cartesian origin of the robot models in BPS.

For successful calibration, you must create an additional frame with a predefined offset in the Z-axis.

Switch to the Data tab, expand photoneo_common -> frame, and double-click fBaseLink to open it.

Set the Z value from the offset table on this documentation page.

Change fBaseLink

2.2.4 Socket configuration

For communication with the vision controller, configure two sockets (one server and one client).

In your project, go to the Home tab. In the Controller section, select Physical IO’s. In the Physical IOs table, right-click Sockets and select Edit Board.

Editing Sockets

In the window that opens, click the “+” button and select Tcp client to configure the client socket.

Adding sockets

Use the values in the table below. After you configure the client socket, click the “+” button again and select Tcp server. Configure the server socket with the values in the table.

Parameter

Tcp client

Tcp server

Name

PhotoneoClient

PhotoneoStateServer

Port

11003

11004

Description

Photoneo Client

Photoneo Robot State Server

Timeout (s)

0

5

End of string

10

10

Server IP

IP address of the Vision controller (Robot interface)

—

Nagle

Unchecked

Unchecked

When you are done, your sockets should look like the figures below.

Socket client
Socket server
Click OK to apply the changes.
Now link the two sio variables to the existing sockets.
Go to the Data tab and expand the sio field. It contains sPHOCLIENT and sPHOSTATE.
To link the sio variables to the sockets, double-click sPHOCLIENT and select Sockets\PhotoneoClient in the Io field.
Repeat this for sPHOSTATE and select Sockets\PhotoneoStateServer.

Both variables are now linked to the physical IOs.

Sio linking

2.2.5 Transferring the files

In your project, go to the Home tab. In the Controller section, select Transfer Manager and select the target robot controller.

Transfer manager 1

If the connection between the SRS and the robot controller is valid, a dialog window opens.

You changed the IO and VAL3 Applications in the SRS project. Select these items on the left side and click the “>>” button to transfer the files to the robot controller.

Note: If a file is changed on the robot controller, select the matching item on the right side (robot controller) to transfer the file to the SRS project.

Transfer manager 2

2.2.6 Loading the example program

After the project applications are transferred to the robot controller, load the main program with the teach pendant.

Select the VAL3 section on the main page.
Go to the Storage section and select the example program that you want to use. To load the application, use the “⇧” button. To select the start mode of the application (manual, autoload, or autostart), click the edit button next to it.

Note: In older versions, applications were loaded from the “old menu”. To open it, press the hardware menu button (☰).

Loading main program

Start modes:

Starting modes

The robot controller is now configured to work with BPS.

3 Robot module

The Robot module is designed for easy integration into existing applications written in the VAL3 language.

3.1 Robotic API

Note: We strongly recommend that you read the Photoneo robotic API before this section.

This section describes the API calls of the Robot module. Use these procedures for high-level control of the bin picking application.

3.1.1 Connection procedures

Warning: These procedures are contained in the photoneo_common API section and must not be edited!

Connection procedure

Description / Usage

Connect to Action Request Server

start
(
)
Description
Starts a background task that establishes a new connection to the Action Request Server.
Usage
Call the procedure only once, at the beginning of the program.

Wait for connection to Action Request Server

wait_for_server
(
)
Description
Blocks the execution of the program until a valid connection to the Action Request Server is established.
Usage
This command usually runs right after the procedure Connect to Action Request Server.

3.1.2 Communication procedures

Note: For a detailed description of these procedures, see Action Requests.

Warning: These procedures are contained in the photoneo_common API section and must not be edited!

Bin picking requests

Request

Input variables

Output variables

Initialization request

initialize_request
(
num x_nVisionSystemID,
joint x_jStartPose,
joint x_jEndPose
)

x_nVisionSystemID - vision system ID

x_jStartPose - start joint pose

x_jEndPose - end joint pose

nErrCode - error code [global variable]

Scan request

scan_request
(
num x_nVisionSystemID
)

x_nVisionSystemID - vision system ID

nErrCode - result of sending the request

Note: The Wait for scan completion procedure receives the response.

Trajectory request

trajectory_request
(
num x_nVisionSystemID
)

x_nVisionSystemID - vision system ID

nErrCode - result of sending the request

Note: The Receive trajectory procedure receives the response.

Pick-failed request

pick_failed
(
num x_nVisionSystemID
)

x_nVisionSystemID - vision system ID

nErrCode - error code [global variable]

Calibration requests

Request

Input variables

Output variables

Add calibration point request

calib_add_point_request
(
)

—

nErrCode - error code [global variable]

Solution requests

Request

Input variables

Output variables

Change solution request

change_solution_request
(
num x_nSolutionID
)

x_nSolutionID - solution ID

nErrCode - error code [global variable]

Start solution request

start_solution_request
(
num x_nSolutionID
)

x_nSolutionID - solution ID

nErrCode - error code [global variable]

Stop solution request

stop_solution_request
(
)

—

nErrCode - error code [global variable]

Get running solution request

get_running_solution_request
(
)

—

nErrCode - error code [global variable]

nRunningSolutionID - solution ID [global variable]

Get available solutions request

get_available_solutions_request
(
)

—

nErrCode - error code [global variable]

nNumAvailSolutions - total count of available solutions [global variable]

nAvailableSolutions - array of available solution IDs; the first ID is at index 0, the last at index nNumAvailSolutions-1 [global variable]

Response receiving procedures

Response receiving procedures

Input variables

Output variables

Wait for scan completion

wait_for_scan_completition
(
)

—

nErrCode - error code [global variable]

Receive trajectory

trajectory_receive
(
)

—

nErrCode - error code [global variable]

nToolInvID - tool point invariance [global variable]

nGrippingPointID - gripping point ID [global variable]

nGrippingPointInvID - gripping point invariance [global variable]

3.1.3 Bin picking procedures

Note: These procedures are in the customer_definitions API section. Implement (edit) them as your application requires.

Bin picking procedure

Description / Usage

Gripper attach

gripper_attach
(
)
Description
A user-defined procedure. Typically, it is the attach procedure for grasping the picked object in the Grasp waypoint.
Usage
It runs automatically when the robot reaches a grasping method waypoint that is configured to run the Attach procedure.

Gripper detach

gripper_detach
(
)
Description
A user-defined procedure. Typically, it is the detach procedure for releasing the picked object in the placing routine that the robot operator defines.
Usage
It runs automatically when the robot reaches a grasping method waypoint that is configured to run the Detach procedure.

Note: Typically, this procedure is not configured to run automatically in a waypoint. It is called during placing, which the robot operator implements.

Gripper user-defined 1

gripper_user_1
(
)
Description
A user-defined procedure.
Usage
It runs automatically when the robot reaches a grasping method waypoint that is configured to run the User 1 procedure.

Gripper user-defined 2

gripper_user_2
(
)
Description
A user-defined procedure.
Usage
It runs automatically when the robot reaches a grasping method waypoint that is configured to run the User 2 procedure.

Gripper user-defined 3

gripper_user_3
(
)
Description
A user-defined procedure.
Usage
It runs automatically when the robot reaches a grasping method waypoint that is configured to run the User 3 procedure.

Execute bin picking routine

pick_part
(
)
Description
Predefined procedure that runs the bin picking routine. You must not edit this procedure directly. To adapt the execution settings, see Bin picking routine execution settings.
Usage
Run it after the bin picking trajectory is received. The robot must be in the start pose when the procedure starts. At the end of the procedure, the robot is in the end pose with the picked object attached to the gripper.

Warning: If you use multiple start poses (different for each vision system), make sure that the robot is in the correct one before you run this procedure.

3.1.4 Auxiliary procedures

Warning: These procedures are contained in the photoneo_common API section and must not be edited!

Auxiliary procedure

Description / Usage

Set communication timeout

set_request_timeout
(
num x_nTimeout
)
Description
Sets a timeout for the next communication procedures. By default, the timeout is zero (no timeout).

Input parameters:

x_nTimeout - timeout value

Usage
Use it when a communication procedure needs a specific timeout.

3.2 Example programs

This section contains basic example programs. Each program is for a specific bin picking application and shows the correct use of the robotic API.

These templates also contain simple error handling. It is only an example. You must define your own routines for error situations.

In its start() procedure, every example program:

  • starts the background communication task and the state server - photoneo_common:start()

  • creates the main task (main program) - main()

  • creates a watchdog that monitors the main task - watchdog_main()

The start procedure of the Basic bin picking example:

call photoneo_common:start()

// Start PHOMAIN task
// Comment this code, when you can calibrate
if((taskStatus("PHOMAIN") == -1))
  taskCreate "PHOMAIN", 50, main()
endIf

// Start WATCHDOG task
if((taskStatus("WATCHDOG") == -1))
  taskCreate "WATCHDOG", 50, watchdog_main()
endIf
The watchdog checks the state of the main task every second. If the main task ends, the watchdog restarts it immediately.
The watchdog procedure of the Basic bin picking example:
while(true)
  // Check PHOMAIN State
  if((taskStatus("PHOMAIN") == -1))
    popUpMsg("Main program is down! Restarting...")
    taskCreate "PHOMAIN", 50, main()
  endIf
  // Check Tasks State Every Second
  delay(1)
endWhile

3.2.1 Basic bin picking example

This program is a very basic example of a simple bin picking application. It connects to the vision controller and initializes one vision system. Then, in a loop, it requests a scan and a trajectory, and executes the received trajectory.

Name: main_basic (in the example_programs folder)

//---------------------------------------------------------------
// Copyright (c) 2021 Photoneo s.r.o.
// All rights reserved
// Description: Photoneo Staubli Module v.1.6.0 - Main Module
//              Adopt this program to meet your requirements
//---------------------------------------------------------------
//                                         BIN PICKING
// This is a basic bin picking template. The main program loop is defined here. User is expected to reteach
// bin picking start and end positions, set IP Address and Port of Vision Controller and adopt placing part
// of the code to meet specific workcell and application requirements here.

// Clear error counter for err_handling procedure
l_nErrorCounter = 0

//  Wait for connection to the Vision Controller
call photoneo_common:wait_for_server()

// Send bin picking initialization request to the Vision Controller,
call photoneo_common:initialize_request(1, jStartPose, jEndPose)

// Move robot away from scanning area - reteach this position for your robot and workcell
movej(jHomePose, flange, mNomSpeed)
waitEndMove()

// When robot is away from scanning area, trigger first scan and localization
call photoneo_common:scan_request(1)

// Initial wait - this enables localization to find first parts
delay(5)

while true
  //==================== PHOTONEO BIN PICKING START ===========================
  // Wait until scanning is completed
  call photoneo_common:wait_for_scan_completition()

  // Check Error Status
  if(photoneo_common:nErrCode == photoneo_common:nOK)

    // Trigger trajectory planning
    call photoneo_common:trajectory_request(1)

    // While trajectory is being calculated, move robot to bin picking start position
    movej(jStartPose, flange, mNomSpeed)

    // Calculated trajectory is received here
    call photoneo_common:trajectory_receive()

    // If trajectory is valid pick part execute bin picking application
    call customer_definitions:pick_part()

  endIf
  // Check Error Status
  if(photoneo_common:nErrCode == photoneo_common:nOK)

    //=================== PHOTONEO BIN PICKING END ===========================

    // Clear error counter if result is ok
    l_nErrorCounter = 0

    //==================== PLACING START ==================================
    // Adopt code for placing operations
    movej(jHomePose, flange, mNomSpeed)
    waitEndMove()

    // Triger next scan and localization, trajectory for next cycle is calculated while object is being placed
    call photoneo_common:scan_request(1)

    // Implement placing procedure

    //==================== PLACING END ==================================

  else

    //                                         ERROR HANDLING
    // Several error situations might occur during bin picking procedure. Some of them are more serious some are less.
    // For example if no part is found or trajectory planning fails, program just tries to repeat the whole sequence. However if
    // communication failure is detected, program is halted immediately. It is possible to adopt this behavior here if needed

    // In case of communication failure, VAL3 program is terminated immediatelly
    if(photoneo_common:nErrCode == photoneo_common:nERR_COM_FAILURE or photoneo_common:nErrCode == photoneo_common:nERR_BAD_DATA or photoneo_common:nErrCode == photoneo_common:nERR_TIMEOUT)
      popUpMsg("Communication failure")
      movej(jHomePose, flange, mNomSpeed)
      waitEndMove()
      return

      //If bin picking service returned error response, reinitialize and trigger new scan (Adopt if needed)
    elseIf(photoneo_common:nErrCode == photoneo_common:nERR_SERVICE or photoneo_common:nErrCode == photoneo_common:nERR_NOT_INITIALIZED)
      popUpMsg("Service error from VC")
      movej(jHomePose, flange, mNomSpeed)
      waitEndMove()
      return

      //  If planning failed or no part was found, notify user and continue by next scan (Adopt if needed)
    elseIf(photoneo_common:nErrCode == photoneo_common:nERR_PLANNING_FAILED or photoneo_common:nErrCode == photoneo_common:nERR_NO_PART_FOUND)
      popUpMsg("No part found or planning failed")
      movej(jHomePose, flange, mNomSpeed)
      waitEndMove()
      call photoneo_common:scan_request(1)
    endIf

    l_nErrorCounter = l_nErrorCounter + 1
    if(l_nErrorCounter > 2)
      return
    endIf

  endIf
endWhile

3.2.2 Multiple Vision Systems example

This program extends the basic bin picking example. It initializes two vision systems instead of one and switches between them in each cycle.

Name: main_multiple_vs (in the example_programs folder)

//---------------------------------------------------------------
// Copyright (c) 2021 Photoneo s.r.o.
// All rights reserved
// Description: Photoneo Staubli Module v.1.6.0 - Main Module with Multiple Vision Systems
//              Adopt this program to meet your requirements
//---------------------------------------------------------------
//                                         BIN PICKING
// This is a basic bin picking template. The main program loop is defined here. User is expected to reteach
// bin picking start and end positions, set IP Address and Port of Vision Controller and adopt placing part
// of the code to meet specific workcell and application requirements here.

// Clear error counter for err_handling procedure
l_nErrorCounter = 0

// Wait for connection to the Vision Controller
call photoneo_common:wait_for_server()

//Define Vision System IDs
l_nVS_ID1 = 1
l_nVS_ID2 = 2

// Send bin picking initialization request to the Vision Controller
call photoneo_common:initialize_request(l_nVS_ID1, jStartPose1, jEndPose1)

// Send bin picking initialization request to the Vision Controller
call photoneo_common:initialize_request(l_nVS_ID2, jStartPose2, jEndPose2)

// Move robot away from scanning area - reteach this position for your robot and workcell
movej(jHomePose, flange, mNomSpeed)
waitEndMove()

// Set Vision System ID
l_nVS_ID = l_nVS_ID1

// When robot is away from scanning area, trigger first scan and localization
call photoneo_common:scan_request(l_nVS_ID)

// Initial wait - this enables localization to find first parts
delay(5)

while true
  //==================== PHOTONEO BIN PICKING START ===========================
  // wait until scanning is completed
  call photoneo_common:wait_for_scan_completition()

  // Check Error Status
  if(photoneo_common:nErrCode == photoneo_common:nOK)

    // Trigger trajectory planning
    call photoneo_common:trajectory_request(l_nVS_ID)

    // While trajectory is being calculated, move robot to bin picking start position
    if(l_nVS_ID == l_nVS_ID1)
      movej(jStartPose1, flange, mNomSpeed)
    else
      movej(jStartPose2, flange, mNomSpeed)
    endIf

    // Calculated trajectory is received here
    call photoneo_common:trajectory_receive()

    // If trajectory is valid pick part execute bin picking application
    call customer_definitions:pick_part()

  endIf
  // Check Error Status
  if(photoneo_common:nErrCode == photoneo_common:nOK)

    //=================== PHOTONEO BIN PICKING END ===========================

    // Clear error counter if result is ok
    l_nErrorCounter = 0

    //==================== PLACING START ==================================
    // Adopt code for placing operations
    movej(jHomePose, flange, mNomSpeed)
    waitEndMove()

    // Switch Vision Systems IDs
    if(l_nVS_ID == l_nVS_ID1)
      l_nVS_ID = l_nVS_ID2
    else
      l_nVS_ID = l_nVS_ID1
    endIf

    // Triger next scan and localization, trajectory for next cycle is calculated while object is being placed
    call photoneo_common:scan_request(l_nVS_ID)

    // Implement placing procedures
    // Use Vision System ID to differentiate between placing procedures

    // ==================== PLACING END ==================================

  else

    //                                         ERROR HANDLING
    // Several error situations might occur during bin picking procedure. Some of them are more serious some are less.
    // For example if no part is found or trajectory planning fails, program just tries to repeat the whole sequence. However if
    // communication failure is detected, program is halted immediately. It is possible to adopt this behavior here if needed

    // In case of communication failure, VAL3 program is terminated immediatelly
    if(photoneo_common:nErrCode == photoneo_common:nERR_COM_FAILURE or photoneo_common:nErrCode == photoneo_common:nERR_BAD_DATA or photoneo_common:nErrCode == photoneo_common:nERR_TIMEOUT)
      popUpMsg("Communication failure")
      movej(jHomePose, flange, mNomSpeed)
      waitEndMove()
      return

      //If bin picking service returned error response, reinitialize and trigger new scan (Adopt if needed)
    elseIf(photoneo_common:nErrCode == photoneo_common:nERR_SERVICE or photoneo_common:nErrCode == photoneo_common:nERR_NOT_INITIALIZED)
      popUpMsg("Service error from VC")
      movej(jHomePose, flange, mNomSpeed)
      waitEndMove()
      return

      //  If planning failed or no part was found, notify user and continue by next scan (Adopt if needed)
    elseIf(photoneo_common:nErrCode == photoneo_common:nERR_PLANNING_FAILED or photoneo_common:nErrCode == photoneo_common:nERR_NO_PART_FOUND)
      popUpMsg("No part found or planning failed")
      movej(jHomePose, flange, mNomSpeed)
      waitEndMove()
      call photoneo_common:scan_request(l_nVS_ID)
    endIf

    l_nErrorCounter = l_nErrorCounter + 1
    if(l_nErrorCounter > 2)
      return
    endIf

  endIf
endWhile

3.2.3 Change solution example

One robotic cell can take part in several production processes. To handle multiple parts at the same time, use multiple vision systems in one solution. If you change the production process completely, it is better to have separate solutions. The robot can deploy them directly.

This program extends the basic bin picking example. After a defined number of bin picking cycles, it sends a request to change the deployed solution.

Name: main_change_solution (in the example_programs folder)

//---------------------------------------------------------------
// Copyright (c) 2021 Photoneo s.r.o.
// All rights reserved
// Description: Photoneo Staubli Module v.1.6.0 - Main Module with Solution Change
//              Adopt this program to meet your requirements
//---------------------------------------------------------------
//                                         BIN PICKING
// This is a basic bin picking template. The main program loop is defined here. User is expected to reteach
// bin picking start and end positions, set IP Address and Port of Vision Controller and adopt placing part
// of the code to meet specific workcell and application requirements here.

// Clear error counter for err_handling procedure
l_nErrorCounter = 0

//  Wait for connection to the Vision Controller
call photoneo_common:wait_for_server()

// Define Solution IDs
l_nSol_ID1 = 2
l_nSol_ID2 = 3

// Set Solution ID
l_nSol_ID = l_nSol_ID1

// Maximum count of picked parts to change solution
l_nMAX_PICKS = 10

// Initialize picked parts counter
l_nPickCounter = 0

// Send bin picking initialization request to the Vision Controller
if (l_nSol_ID==l_nSol_ID1)
  call photoneo_common:initialize_request(1, jStartPose1, jEndPose1)
else
  call photoneo_common:initialize_request(1, jStartPose2, jEndPose2)
endIf

// Move robot away from scanning area - reteach this position for your robot and workcell
movej(jHomePose, flange, mNomSpeed)
waitEndMove()

// When robot is away from scanning area, trigger first scan and localization
call photoneo_common:scan_request(1)

// Initial wait - this enables localization to find first parts
delay(5)

while true
  //==================== PHOTONEO BIN PICKING START ===========================
  // Wait until scanning is completed
  call photoneo_common:wait_for_scan_completition()

  // Check Error Status
  if(photoneo_common:nErrCode == photoneo_common:nOK)

    // Trigger trajectory planning
    call photoneo_common:trajectory_request(1)

    // While trajectory is being calculated, move robot to bin picking start position
    if(l_nSol_ID == l_nSol_ID1)
      movej(jStartPose1, flange, mNomSpeed)
    else
      movej(jStartPose2, flange, mNomSpeed)
    endIf

    // Calculated trajectory is received here
    call photoneo_common:trajectory_receive()

    // If trajectory is valid pick part execute bin picking application
    call customer_definitions:pick_part()

    // Increment picked parts counter
    l_nPickCounter = l_nPickCounter + 1

  endIf
  // Check Error Status
  if(photoneo_common:nErrCode == photoneo_common:nOK)

    //=================== PHOTONEO BIN PICKING END ===========================

    // Clear error counter if result is ok
    l_nErrorCounter = 0

    //==================== PLACING START ==================================
    // Adopt code for placing operations
    movej(jHomePose, flange, mNomSpeed)
    waitEndMove()

    if(l_nPickCounter < l_nMAX_PICKS)
      // Triger next scan and localization, trajectory for next cycle is calculated while object is being placed
      call photoneo_common:scan_request(1)

      // Implement place procedures
      // Use Vision System ID to differentiate between placing procedures
    else
      // Reset picked parts counter
      l_nPickCounter = 0

      // Implement place procedures
      // Use Vision System ID to differentiate between placing procedures

      // Change solution
      if(l_nSol_ID == l_nSol_ID1)
        l_nSol_ID = l_nSol_ID2
      else
        l_nSol_ID = l_nSol_ID1
      endIf
      call photoneo_common:change_solution_request(l_nSol_ID)

      // Reinitialization after solution change
      // Send bin picking initialization request to the Vision Controller
      if(l_nSol_ID == l_nSol_ID1)
        call photoneo_common:initialize_request(1,jStartPose1,jEndPose1)
      else
        call photoneo_common:initialize_request(1,jStartPose2,jEndPose2)
      endIf

      // Move robot away from scanning area - reteach this position for your robot and workcell
      movej(jHomePose,flange,mNomSpeed)
      waitEndMove()

      // When robot is away from scanning area, trigger first scan and localization
      call photoneo_common:scan_request(1)

      // Initial wait - this enables localization to find first parts
      delay(5)

    endIf

    // ==================== PLACING END ==================================

  else

    //                                         ERROR HANDLING
    // Several error situations might occur during bin picking procedure. Some of them are more serious some are less.
    // For example if no part is found or trajectory planning fails, program just tries to repeat the whole sequence. However if
    // communication failure is detected, program is halted immediately. It is possible to adopt this behavior here if needed

    // In case of communication failure, VAL3 program is terminated immediatelly
    if(photoneo_common:nErrCode==photoneo_common:nERR_COM_FAILURE or photoneo_common:nErrCode==photoneo_common:nERR_BAD_DATA or photoneo_common:nErrCode==photoneo_common:nERR_TIMEOUT)
      popUpMsg("Communication failure")
      movej(jHomePose,flange,mNomSpeed)
      waitEndMove()
      return

      //If bin picking service returned error response, reinitialize and trigger new scan (Adopt if needed)
    elseIf(photoneo_common:nErrCode==photoneo_common:nERR_SERVICE or photoneo_common:nErrCode==photoneo_common:nERR_NOT_INITIALIZED)
      popUpMsg("Service error from VC")
      movej(jHomePose,flange,mNomSpeed)
      waitEndMove()
      return

      //  If planning failed or no part was found, notify user and continue by next scan (Adopt if needed)
    elseIf(photoneo_common:nErrCode==photoneo_common:nERR_PLANNING_FAILED or photoneo_common:nErrCode==photoneo_common:nERR_NO_PART_FOUND)
      popUpMsg("No part found or planning failed")
      movej(jHomePose,flange,mNomSpeed)
      waitEndMove()
      call photoneo_common:scan_request(1)
    endIf

    l_nErrorCounter=l_nErrorCounter+1
    if(l_nErrorCounter>2)
      return
    endIf

  endIf
endWhile

3.2.4 Calibration example

This program is a template for semi-automatic calibration.

Before you run the program:

  • Teach the calibration poses.

  • Start the calibration in BPS.

Now you can start the program. The robot moves to each calibration pose and sends the Add calibration point request when it reaches the pose. When all calibration points are added, the program ends. If you are satisfied with the calibration result, save it in BPS.

Name: main_calibration (in the example_programs folder)

//----------------------------------------------------------------------
// Copyright (c) 2021 Photoneo s.r.o.
// All rights reserved
// Description: Photoneo Staubli Module v.1.6.0 -  Calibration Example
//              Reteach points and use as many as you need
//----------------------------------------------------------------------

//                                         CALIBRATION
// Reteach calibration positions and call add calibration point request after reaching each calibration pose
// It it recomended to run calibration in MANUAL mode step by step to have a proper control over the process.
// Always make sure that robot does not collide with workcell during transitions between specific waypoints

//  Wait for connection to the the Vision Controller
call photoneo_common:wait_for_server()

// Move to Home position
movej(jHomePose, flange, mNomSpeed)
waitEndMove()

// Starts adding points
movej(jCalib1, flange, mNomSpeed)
waitEndMove()
call photoneo_common:printLog("Calibration Point 1 reached", "CLIENT")
call photoneo_common:calib_add_point_request()

if(photoneo_common:nErrCode!=photoneo_common:nOK)
  call photoneo_common:printLog("Error while adding the calibration point","CLIENT")
  delay(5)
  return
endIf

movej(jCalib2, flange, mNomSpeed)
waitEndMove()
call photoneo_common:printLog("Calibration Point 2 reached", "CLIENT")
call photoneo_common:calib_add_point_request()

if(photoneo_common:nErrCode!=photoneo_common:nOK)
  call photoneo_common:printLog("Error while adding the calibration point","CLIENT")
  delay(5)
  return
endIf

movej(jCalib3, flange, mNomSpeed)
waitEndMove()
call photoneo_common:printLog("Calibration Point 3 reached", "CLIENT")
call photoneo_common:calib_add_point_request()

if(photoneo_common:nErrCode!=photoneo_common:nOK)
  call photoneo_common:printLog("Error while adding the calibration point","CLIENT")
  delay(5)
  return
endIf

movej(jCalib4, flange, mNomSpeed)
waitEndMove()
call photoneo_common:printLog("Calibration Point 4 reached", "CLIENT")
call photoneo_common:calib_add_point_request()

if(photoneo_common:nErrCode!=photoneo_common:nOK)
  call photoneo_common:printLog("Error while adding the calibration point","CLIENT")
  delay(5)
  return
endIf

movej(jCalib5, flange, mNomSpeed)
waitEndMove()
call photoneo_common:printLog("Calibration Point 5 reached", "CLIENT")
call photoneo_common:calib_add_point_request()

if(photoneo_common:nErrCode!=photoneo_common:nOK)
  call photoneo_common:printLog("Error while adding the calibration point","CLIENT")
  delay(5)
  return
endIf

movej(jCalib6, flange, mNomSpeed)
waitEndMove()
call photoneo_common:printLog("Calibration Point 6 reached", "CLIENT")
call photoneo_common:calib_add_point_request()

if(photoneo_common:nErrCode!=photoneo_common:nOK)
  call photoneo_common:printLog("Error while adding the calibration point","CLIENT")
  delay(5)
  return
endIf

movej(jCalib7, flange, mNomSpeed)
waitEndMove()
call photoneo_common:printLog("Calibration Point 7 reached", "CLIENT")
call photoneo_common:calib_add_point_request()

if(photoneo_common:nErrCode!=photoneo_common:nOK)
  call photoneo_common:printLog("Error while adding the calibration point","CLIENT")
  delay(5)
  return
endIf

movej(jCalib8, flange, mNomSpeed)
waitEndMove()
call photoneo_common:printLog("Calibration Point 8 reached", "CLIENT")
call photoneo_common:calib_add_point_request()

if(photoneo_common:nErrCode!=photoneo_common:nOK)
  call photoneo_common:printLog("Error while adding the calibration point","CLIENT")
  delay(5)
  return
endIf

movej(jCalib9, flange, mNomSpeed)
waitEndMove()
call photoneo_common:printLog("Calibration Point 9 reached", "CLIENT")
call photoneo_common:calib_add_point_request()

if(photoneo_common:nErrCode!=photoneo_common:nOK)
  call photoneo_common:printLog("Error while adding the calibration point","CLIENT")
  delay(5)
  return
endIf


// Move back to Home position
movej(jHomePose, flange, mNomSpeed)
waitEndMove()

3.3 Error handling

If an error occurs while the requested operation runs, the error is stored in the global variable photoneo_common:nErrCode. We recommend that you add suitable error handling for your application after each synchronous request and response receiving procedure.

For the list of error codes with descriptions and troubleshooting, see here.

The most important error codes are defined as constants in the application photoneo_common. These error codes are:

Error code

VAL3 constant

No error (0)

nOK := 0

Service error (1)

nERR_SERVICE := 1

Communication error (3)

nERR_COM_FAILURE := 3

Bad data (4)

nERR_BAD_DATA := 4

Timeout (5)

nERR_TIMEOUT := 5

Path planning failed (201)

nERR_PLANNING_FAILED := 201

No object found (202)

nERR_NO_PART_FOUND := 202

Vision system not initialized (203)

nERR_NOT_INITIALIZED := 203

Empty scene (218)

nERR_EMPTY_SCENE := 218

Wrong bin picking configuration (255)

nERR_WRONG_BP_CONF := 255

Note: Example programs provide basic error handling.

4 Running the basic bin picking example program

4.1 Prerequisites

Before you can run the Basic bin picking example, make sure that:

  • A fully configured BPS solution with a single vision system is ready for deployment.

  • The robot controller is configured as described in Robot controller setup.

  • The BPS network settings are configured.

  • The gripper procedures are implemented (optional - without them, the robot does not actually pick the object).

  • The placing procedure is implemented.

4.2 Bin picking routine execution settings

The application customer_definitions contains the array mPickingSpeed. Use it to set the parameters of the individual trajectories of the bin picking routine.
In the array, you can set the speeds, accelerations, and path approximations.

By default, the speeds of the first 4 trajectories of the bin picking routine are configured. (The default number of trajectories in a bin picking routine is 4, as defined in the grasping method of the BPS solution.)

Speed customization 1
Speed customization 2

Adapt these values to your requirements. If you add custom path stages (trajectories), configure the matching number of values in the mPickingSpeed array. Keep the order of the trajectories: the first row in the mPickingSpeed array applies to the first trajectory, the second row to the second trajectory, and so on.

4.3 Reteach the robot poses

An important step of the bin picking configuration is to teach the home, start, and end poses. Teach the home position so that the robot is outside the scanning area. Teach the start position so that the robot gripper is approximately above the center of the bin. The end position can be similar to the start position or slightly shifted towards the placing area. Do not define the end pose too far from the bin. This can affect path planning (longer total planning time, planning errors, and so on).

The basic bin picking example program uses the following poses:

jHomePose - Home position

jStartPose - Start position

jEndPose - End position

To teach the poses, go to the Memory tab in the VAL3 section. Select the loaded main program and select the edit option. The Data tab shows a list of the program variables. To select the pose that you want to teach, click the arrow next to it.

Teaching poses 1

Then click the teach button to open the teaching dialog.

Teaching poses 2

4.4 Runtime

Deploy your BPS solution. On the Deployment page in BPS, the Action Request Client status should be DISCONNECTED (from the Action Request Server).

Select the Manual mode or the Auto mode (reset the safety if needed) and start the main program.

Check the Binpicking Client Log to see if a valid connection to the vision controller is established (message: Connection to the Vision Controller Successful).

Running the program

On the Deployment page, the Action Request Client status changes to CONNECTED.

Depending on the robot controller mode (Manual / Auto), you may need to press (and hold) Power (Button I) and Play (Button II) to enable robot motion.

Enabling power

The robot now starts to send requests to the vision controller and to execute bin picking movements.

Note: Be ready to stop the robot motion immediately. We strongly recommend that you reduce the speed to 10% of the maximum during the first bin picking tests.

5 Migration guide

This chapter describes how to update your Robot module to a newer version.

5.1 Robot module update

Follow these steps to update your current Robot module to a newer version that is compatible with your BPS version:

  1. Back up the current application customer_definitions. It contains your custom settings and the gripper action procedures.

  2. Remove the old applications: photoneo_common and customer_definitions.

  3. Load the new applications: photoneo_common and customer_definitions.

  4. Apply your changes from the old customer_definitions to the new customer_definitions.

  5. Read the API changes in the new version of the Robot module carefully. If necessary, update the API calls in your main program.